#ifndef RONode_H
#define RONode_H
#include <QObject>
#include <QQmlComponent>
#include "ROComponent.h"

class ROPlayer;
class ROComponent;
class RONodePrivate;
class RORPC;
class ROSyncCreation;

class RONode:public QObject
{
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(QUrl host READ host WRITE setHost NOTIFY hostChanged FINAL)
    Q_PROPERTY(State state READ state NOTIFY stateChanged FINAL)
    Q_PROPERTY(QString errString READ errString NOTIFY errStringChanged FINAL)
    Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL)
public:
    enum State
    {
        Offline,//离线状态
        Connecting,//链接中
        Initializing,//初始化中
        Ready//准备完毕
    };
    Q_ENUM(State);

    enum Error{
        NoError,
        ConnectionFailed,//向服务端连接出错了
        ConnectionRejected,//被服务端拒绝了
        LostConnection,//服务器突然断开
        Kicked,//被服务器踢出了
        Logout,//已登出
        ServerClosed//服务端关闭了
    };
    Q_ENUM(Error)

    RONode();
    ~RONode();

    QUrl host() const;
    void setHost(const QUrl &newHost);

    State state() const;
    QString errString() const;


    bool active() const;
    void setActive(bool newActive);

    QVariantMap loginParam() const;
    void setLoginParam(const QVariantMap &newLoginParam);

    int playerId() const;

    QQmlComponent *rootComponent() const;
    void setRootComponent(QQmlComponent *newRootComponent);

    QObject *rootObject() const;
    void setRootObject(QObject *newRootObject);

    Error error() const;


private:
    void setErrString(const QString &newErrString);
    void setState(State newState);
    void setPlayerId(int newPlayerId);
    void setError(Error newError);
signals:
    void hostChanged();

    void stateChanged();

    void errStringChanged();

    void activeChanged();

    void loginParamChanged();

    void playerIdChanged();

    void rootComponentChanged();

    void rootObjectChanged();

    void errorChanged();

private:
    void connectToHost();
    void onConnected();
    void onDisConnected();
    void onMessage(QString topic,QVariant value);
    void initScene(const QVariant& value);
    void disconnectFromHost();
    void rpcCall(int id,QString name,const QVariantList& params,bool isSafe);
    void handleRPC(const QVariantMap &v);
    void cleanScene();
    QObject* getObjectById(int id);
    void markError(Error err,QString errStr);
    void clearError();
private:
    QVariantMap m_loginParam;//连接参数,当客户端连接完成后该参数会赋给对应的player

    QQmlComponent* m_rootComponent = nullptr;
    QUrl m_host;//服务器地址
    State m_state = Offline;
    Error m_error = NoError;
    QString m_errString;
    bool m_active = false;
    int m_playerId = 0;//连接到服务端后通过这个可以获取到玩家的id
    QObject* m_rootObject = nullptr;//根对象

    RONodePrivate *_P = nullptr;
    friend class RONodePrivate;
    friend class RORPC;
    friend class ROSyncCreation;
    Q_PROPERTY(QVariantMap loginParam READ loginParam WRITE setLoginParam NOTIFY loginParamChanged FINAL)
    Q_PROPERTY(int playerId READ playerId NOTIFY playerIdChanged FINAL)
    Q_PROPERTY(QQmlComponent *rootComponent READ rootComponent WRITE setRootComponent NOTIFY rootComponentChanged FINAL)//根组件
    Q_PROPERTY(QObject *rootObject READ rootObject WRITE setRootObject NOTIFY rootObjectChanged FINAL)
    Q_PROPERTY(Error error READ error NOTIFY errorChanged FINAL)
};


#endif
